package eu.epfc.dnet.mastermind.hibernate;

import eu.epfc.dnet.mastermind.model.beans.Token;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author Pierre Buvé & Nicolas Van Damme
 */
public class TgamesHelper {

    Session session = null;
    TusersHelper tusersHelper = new TusersHelper();

    public TgamesHelper() {
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
    }

    /**
     * Crée une nouvelle partie dans la base de donnée et retourne ses informations.
     * @param username
     * @param listSolution
     * @return 
     */
    public Tgames createAndGetNewGame(String username, List<Token> listSolution) {
        Transaction tx = session.beginTransaction();
        Tgames tgames = new Tgames();
        tgames.setTusers(tusersHelper.getUserByUsername(username));
        tgames.setCreationDate(new Date());
        tgames.setSol01(listSolution.get(0).getColor());
        tgames.setSol02(listSolution.get(1).getColor());
        tgames.setSol03(listSolution.get(2).getColor());
        tgames.setSol04(listSolution.get(3).getColor());
        tgames.setStatus("NEW");
        session.save(tgames);
        session.refresh(tgames);
        tx.commit();
        return tgames;
    }

    /**
     * Retourne les informations d'une partie selon l'id fourni en paramètre
     * @param gameId
     * @return 
     */
    public Tgames getGameByGameId(int gameId) {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery("from Tgames games where games.id = " + gameId);
        Tgames tgames = (Tgames) q.list().get(0);
        System.out.println("GameId recu par getGameByGameId :"+gameId);
        System.out.println("Taille de la list de tgames renvoyée :" + q.list().size());
        return tgames;
    }
    
    /**
     * Met à jour les informations de la partie recue en paramètre
     * @param gameId
     * @param status
     * @param duration 
     */
    public void updateGame(int gameId, String status, int duration) {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery("from Tgames games where games.id = " + gameId);
        Tgames tgames = (Tgames) q.list().get(0);
        tgames.setStatus(status);
        tgames.setDuration(duration);
        session.update(tgames);
        tx.commit();        
    }

    /**
     * Retourne le nombre total de partie
     * @return 
     */
    public String getNbrAllGame() {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select count(*) from Tgames game");
        Long nbr = (Long) q.list().get(0);
        return nbr.toString();
    }

    /**
     * Retourne le nombre total de victoire
     * @return 
     */
    public String getNbrVictory() {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select count(*) from Tgames game where status='VICTORY'");
        Long nbr = (Long) q.list().get(0);
        return nbr.toString();
    }

    /**
     * Retourne le nombre total de défaite
     * @return 
     */
    public String getNbrDefeat() {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select count(*) from Tgames game where status='DEFEAT'");
        Long nbr = (Long) q.list().get(0);
        return nbr.toString();
    }

    /**
     * Retourne le nombre total de partie dont le statut est NEW
     * @return 
     */
    public String getNbrNew() {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select count(*) from Tgames game where status='NEW'");
        Long nbr = (Long) q.list().get(0);
        return nbr.toString();
    }

    /**
     * Retourne le nombre total de patie dont le statut est PLAYING
     * @return 
     */
    public String getNbrPlaying() {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select count(*) from Tgames game where status='PLAYING'");
        Long nbr = (Long) q.list().get(0);
        return nbr.toString();
    }

    /**
     * Retourne le nombre de secondes de la partie la plus longue 
     * @return 
     */
    public Integer getMaxTime() {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select max(duration) from Tgames");
        Integer nbr = (Integer) q.list().get(0);
        return nbr;
    }
    
    /**
     * Retourne la liste des parties de l'utilisateur recu en paramètre d'apres le status recu en paramètre.
     * @param username
     * @param status
     * @return 
     */
    public List<Tgames> getGameListForUserByStatus(String username, String status) {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("from Tgames games where games.status = '"+ status + "' and tusers.username = '" + username +"'");
        List<Tgames> listTgames = q.list();
        return listTgames;
    }

    /**
     * Retourne la durée d'une partie selon le gameid recu en paramètre
     * @param gameId
     * @return 
     */
    public int getDurationForGameId(int gameId) {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select game.duration from Tgames game where (game.id='"+gameId+"')");
        Integer nbr = (Integer) q.list().get(0);
        return nbr;
    }

    /**
     * Retourne le nombre total de fois qu'une couleur envoyer en paramètre est sortie dans une solution
     * @param couleur
     * @return 
     */
    public String getNbrCouleurDsSolution(String couleur) {
        Transaction tx = session.beginTransaction();
        Query q = session.createQuery ("select count(*) from Tgames game where (sol01='"+couleur+"') OR (sol02='"+couleur+"') OR (sol03='"+couleur+"') OR (sol04='"+couleur+"')");
        Long nbr = (Long) q.list().get(0);
        return nbr.toString();
    }

   


    

}
